#!/usr/bin/env python

# ------------------------------------------------------------
# ::                        WIGA-SOFT                       ::
# ------------------------------------------------------------
# project.py
# Module for personal reports
# Created by: Wiktor`
# Version: 1.0
# ------------------------------------------------------------

from __future__ import division
from pao.models import Project, Employee, Task, Department, Budget
import datetime

def projectManagerReport(project):
    """
    Input: ProjectID (project) 
    Output: Zodynas (Dictionary) 
    {
      'project': <Projekto pavadinimas>,
      'projectId': <Projekto kodas>,
      'description': <Projekto aprasas>,
      'manager': <Projekto vadovas>,
      'department': <Projekto vadovo skyriaus pavadinimas>,
      'departmentId': <Projekto vadovo skyriaus numeris>,
      'started': <Projekto pradzia>,
      'finished': <Projekto pabaiga>,
      'members':
        [ 
          (<Skyrius>, <SkyeiausId>, <Viso skyriaus isdirbtos valandos>, { <Projekto dalyvio vardas>: <Isdirbo valandu>, ... } ),
          (<Skyrius>, <SkyriausId>, <Viso skyriaus isdirbtos valandos>, { ..... } ),
          ( ..... )
          ( ..... )
        ]
    }    
    """
    
    result = {}
    selectedProject = Project.objects.get(id = project)
    result['project'] = selectedProject.name
    result['projectId'] = selectedProject.id
    result['name'] = selectedProject.name
    result['description'] = None # pateikti aprasa, kai bus available
    result['manager'] = selectedProject.manager.id.username
    result['department'] = selectedProject.manager.department.name
    result['departmentId'] = selectedProject.manager.department.id
    projectTasks = Task.objects.filter(project__exact = project)
    listOfDepartments = []
    dates = []
    for e in projectTasks:
        if e.employee.department not in listOfDepartments:
            listOfDepartments.append(e.employee.department)
        if e.date not in dates:
            dates.append(e.date)
    result['started'] = min(dates)
    myDate = max(dates)
    newYear = myDate.year 
    newMonth = myDate.month + 1
    if newMonth > 12: 
        newYear += 1 
        newMonth = 1
    newDate = datetime.date(newYear, newMonth, myDate.day) 
    result['finished'] = newDate
    members = []
    departments = []
    for e in listOfDepartments:
        departmentTasks = Task.objects.filter(employee__department = e.id)
        departmentTasks = departmentTasks.filter(project__id = project)
        sum = 0
        tmpRez = {}
        for i in departmentTasks:
            if i.employee.id.username not in tmpRez.keys():
                tmpRez[i.employee.id.username] = i.workhours
            else:
                tmpRez[i.employee.id.username] += i.workhours
            sum += i.workhours
        tmpTuple = e.name, e.id, sum, tmpRez
        if e.id == selectedProject.manager.department.id:
            members.append(tmpTuple)
        else:
            departments.append(tmpTuple)
    departments.sort(lambda x, y: int(y[2] - x[2]))
    for e in departments:
        members.append(e)
    result['members'] = members
    return result
            
def projectIntensityReport(project, start=None, end=None):
    """
    Input: ProjectID (project), StartPeriod (start), EndPeriod (end)
        date input format: '2006-01-01'
    Output: List of dictionaries
    [
      {'date': <Metai-Menuo>, 
       'local': <Sio skyriaus darbuotoju isdirbtos valandos siame projekte>, 
       'foreign': <Kitu skyriu darbuotoju isdirbtos valandos siame projekte>,
       'total': <Visu darbuotoju isdirbtos valandos siame projekte (local+foreign)>},
      { .... },
      { .... }
    ]
    """
    
    if start is None:
        start = datetime.date(1990, 1, 1)
    if end is None:
        end = datetime.date.today()
    result = []
    dates = []
    department = Project.objects.get(id = project).manager.department.id
    projectTasks = Task.objects.filter(project__exact = project)
    projectTasks = projectTasks.filter(date__gte = start)
    projectTasks = projectTasks.filter(date__lte = end)
    for e in projectTasks:
        # print str(e.id) + ' ' + str(e.project.id) + ' ' + str(e.employee.id.username) + ' ' + e.date.isoformat() +  ' ' + str(e.workhours)
        if e.date not in dates:
            if e.date >= start:
                if e.date <= end:
                    dates.append(e.date)
    dates.sort()
    if len(dates) > 0:
        i = min(dates)
        endDate = max(dates)
        while i <= endDate:
            tmpRez = {}
            local = 0
            foreign = 0
            tmpProjectTasks = projectTasks.filter(date = i)
            for e in tmpProjectTasks:
                if e.employee.department.id == department:
                    local += e.workhours
                else:
                    foreign += e.workhours
            tmpRez['date'] = i
            tmpRez['local'] = local
            tmpRez['foreign'] = foreign
            tmpRez['total'] = local + foreign
            result.append(tmpRez)
            i = addMonth(i)
    return result
    
def projectBudgetReport(project, start=None, end=None):
    """
    Input: ProjectID (project), StartPeriod (start), EndPeriod (end) 
    Output: List of dictionaries
    [
      {'date': <Metai-Menuo>,
       'total': <To menesio biudzetas>,
       'used': <Isnaudota valandu>,
       'left': <Likutis>,
       'percent': <Likutis procentais>}
      { .... }
      { .... }
    ]
    """
    if start is None:
        start = datetime.date(1990, 1, 1)
    if end is None:
        end = datetime.date.today()
    result = []
    projectTasks = Task.objects.filter(project__exact = project)
    projectTasks = projectTasks.filter(date__gte = start)
    projectTasks = projectTasks.filter(date__lte = end)
    dates = []
    for e in projectTasks:
        if e.date not in dates:
            if e.date >= start:
                if e.date <= end:
                    dates.append(e.date)
    dates.sort()
    projectBudget = Budget.objects.filter(project__exact = project)
    if len(dates) > 0:
        i = min(dates)
        endDate = max(dates)
        while i <= endDate:
            tmpProjectTasks = projectTasks.filter(date = i)
            sum = 0
            tmpRez = {}
            for e in tmpProjectTasks:
                sum += e.workhours
            try:
                budget = projectBudget.get(date = i).workhours
                tmpRez['date'] = i
                tmpRez['total'] = budget
                tmpRez['used'] = sum
                tmpRez['left'] = budget - sum
                tmpRez['percent'] = ((budget - sum) / budget) * 100
            except Budget.DoesNotExist:
                tmpRez['date'] = i
                tmpRez['total'] = 0
                tmpRez['used'] = sum
                tmpRez['left'] = sum * (-1)
                tmpRez['percent'] = None
            result.append(tmpRez)
            i = addMonth(i)
    return result
    
def addMonth(myDate):
    newYear = myDate.year
    newMonth = myDate.month + 1
    if newMonth > 12: 
        newYear += 1 
        newMonth = 1
    newDate = datetime.date(newYear, newMonth, myDate.day)
    return newDate